home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char SccsId[]= "@(#)graph_disp.c 1.18 3/13/95 13:12:15";
- #endif
- /*
- | file name - graph_disp.c
- |===================================================================
- |
- | This program demonstrates how to utilize drawports for
- | graphs to be displayed and manipulated. Each graph may
- | be updated and will be maintained within their own drawport.
- |
- | The program also allows the user to manipulate the graphs
- | in the following manners: Zoom in, Zoom Out, Increase
- | the Range or Decrease the Range of the variables assigned
- | to the graphs and Reset the graphs to their original state.
- |
- | Except for the update operation, each operation is performed
- | only on the currently selected graph which is identified by
- | an arrow.
- |
- | The example shows how the history of the graph is being
- | maintained by the graph and displayed appropriately when
- | redrawing occurs or changes to the ranges of the variable
- | descriptors are made.
- |
- |===================================================================
- */
- #include <windows.h>
- /*
- * DV-Tools header files
- */
- #include "std.h" /* <stdio.h> etc., scalar & macro definitions */
- #include "dvstd.h" /* public types & constants */
- #include "dvtools.h" /* constants used by T routines */
- #include "dvGR.h" /* constants used by window mgt & GR routines */
- #include "VOstd.h" /* constants used by VO & VOob routines */
- #include "Tfundecl.h" /* T routines (screens, drawports & views) */
- #include "VOfundecl.h" /* VO routines (objects) */
- #include "VGfundecl.h" /* VG routines (get info from dgp & vdp) */
- #include "VPfundecl.h" /* VP routines (put info for dgp & vdp) */
- #include "VUerfundecl.h" /* VUer routines (event handling routines) */
-
- /* Constants */
- #define DVPATH (char *)NULL
- #define DISPFORMS_STB (char *)NULL
- #define DVDEVICE (char *)NULL
- #define DVCOLORTABLE (char *)NULL
- #define VIEW_NAME "graph_disp.v"
- #define SCREEN_VIEWPORT (RECTANGLE *)NULL
- #define ENTIRE_DRAWPORT (RECTANGLE *)NULL
- #define MAX_GRAPHS 3
-
- /* Define the selection values from the control menu */
- #define UPDATE 1
- #define ZOOM_IN 2
- #define ZOOM_OUT 3
- #define RESET 4
- #define INCR_RANGE 5
- #define DECR_RANGE 6
- #define QUIT 7
- #define MENU_CLIENT 1
-
- /* Define global variables */
- DRAWPORT main_drawport; /* how & where to display picture, picture frame */
- OBJECT control_menu, /* menu input object */
- msg_object; /* text object used for prompts & messages */
- int current_graph; /* index representing selected graph */
- int Quit = NO; /* flag to quit program */
- float control_var, /* variable buffer for menu input object */
- arrow_var; /* variable buffer for dynamic polygon */
- double CurrentScale[MAX_GRAPHS] = {1.0, 1.0, 1.0};
- double ZoomInScale = 2.0, ZoomOutScale = 0.5;
-
- /* Define list of graph areas and view names with graphs */
- char *Graph_Areas[MAX_GRAPHS] = {"graph1.v", "graph2.v", "graph3.v"};
-
- /* Whole world rectangle, (-16384, -16384) to (16383, 16383)*/
- RECTANGLE whole_world = {XMIN, YMIN, XMAX, YMAX};
-
- /* Define the values to designate where along the path the arrow should be. */
- float graph_arrow_val[MAX_GRAPHS] = {0.0, 0.5, 1.0};
-
- /* Define structure containing graph information */
- typedef struct
- {
- DRAWPORT drawport; /* how & where to display graph view */
- VIEW view; /* picture of graph view */
- OBJECT graph; /* graph object */
- DATAGROUP dgp_ptr; /* pointer to data group structure */
- VARDESC vdplist[MAX_GRAPHS + 1]; /* list of vdps */
- double low_range[MAX_GRAPHS + 1]; /* original low range of vdp */
- double high_range[MAX_GRAPHS + 1];/* original high range of vdp */
- } GRAPH_INFO;
-
- GRAPH_INFO GraphInfo[MAX_GRAPHS];
-
- /* Functions defined in graph_disp.c */
- void GetObjects V_P_((OBJECT screen, OBJECT drawing));
- ADDRESS GetGraph V_P_((OBJECT object, ADDRESS args));
- void GetCurrentDrawport V_P_((DRAWPORT drawport));
- void ChangeRange V_P_((ADDRESS incrdecr));
-
-
- /*
- * MAIN PROGRAM
- */
- int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
- LPSTR lpCmdLine, int nCmdShow )
- {
- INT argc = 0;
- CHAR **argv;
- /*
- * program arguments
- * argv[1] - display device (default is DVDEVICE)
- */
-
- /* Define & initialize device name and view filename */
- char *device_name = DVDEVICE; /* default device name */
- char *view_name = VIEW_NAME; /* default view name */
-
- /* Define display variable */
- OBJECT screen; /* display device, the window */
- VIEW main_view; /* picture representation of the view file */
-
- /* Control loop variables */
- OBJECT location; /* the event representation */
- int event_req_status; /* status of event requests */
-
- /* Other variables */
- DRAWPORT selected_drawport; /* represents current selected drawport */
- OBJECT drawing; /* graphical representation of screen */
- int i; /* counter */
-
- /*-----------------
- * Initialization
- *
- * TInit: perform the initialization of DV-Tools
- * TInit reads your configuration file and any
- * environment variables or logical names set.
- */
- make_argv(&argc,&argv,GetCommandLine());
- TInit( DVPATH, DISPFORMS_STB );
-
- /*
- * TscOpenSet: opens a device as a screen object using
- * specified attributes
- *
- * Set exposure block to YES to insure the window
- * is ready for drawing when TdpDraw is called.
- */
- if (argc > 1)
- device_name = argv[1];
- screen = TscOpenSet (NULL, DVCOLORTABLE,
- V_WINDOW_NAME, "Graph Display",
- V_WINDOW_WIDTH, 700, V_WINDOW_HEIGHT, 700,
- V_X_EXPOSURE_BLOCK, YES,
- V_ACTIVE_CURSOR, V_END_OF_LIST);
- if (!screen)
- {
- printf ("Must specify device on command line or");
- printf (" in DataViews configuration file.\n");
- S_EXIT (EXIT_ERR);
- }
-
- /*
- * VOscWinEventMask: sets the screen's window event mask
- */
- VOscWinEventMask ((ULONG) V_KEYPRESS | V_BUTTONPRESS |
- V_MOTIONNOTIFY | V_EXPOSE | V_RESIZE,
- (ULONG) 0);
-
- /*
- * TviLoad: Load a view in from a file,
- * the view is graph_disp.v
- */
- main_view = TviLoad (view_name);
- if (!main_view)
- {
- printf ("Could not load view from file ");
- printf ("%s.\n", view_name);
- S_EXIT (EXIT_ERR);
- }
-
- /*
- * TdpCreateStretch: Create a DV-tools window, a drawport
- * "drawport" is attached to the screen object, "screen"
- * "view" is the view to be displayed on the screen
- * "SCREEN_VIEWPORT" specifies the area of the screen
- * to use to display the drawport
- * "whole_world" specifies the portion of the view to be
- * displayed, here the whole view
- * The whole view will be stretched to fit in the drawport
- */
- main_drawport = TdpCreateStretch (screen, main_view,
- SCREEN_VIEWPORT, &whole_world);
-
- /*
- * TviGetDrawing: Gets the drawing object which TviLoad created
- * as part of the view structure.
- * GetObjects: Extracts the graph objects from the main view
- * A drawport will be created in which to display
- * each graph object.
- * Then initialize some internal identifiers.
- */
- drawing = TviGetDrawing (main_view);
- GetObjects (screen, drawing);
- current_graph = 0;
- arrow_var = graph_arrow_val[0];
-
- /*
- * TscErase: erase the entire screen in the default background color
- * TscDraw: Draw the contents of the drawport
- * TviOpenData: Open all data source lists for this view and views
- * referenced by enabled subdrawings contained in view.
- * TviReadData: Reads data from the data sources of a view
- *
- * Erase the screen and draw the contents of the main drawport.
- * Then open and read the data source lists for the views containing
- * the graphs and draw their drawports.
- */
- TscErase (screen);
- TdpDraw (main_drawport);
- for (i = (MAX_GRAPHS - 1); i >= 0; i--)
- {
- TviOpenData (GraphInfo[i].view);
- TviReadData (GraphInfo[i].view);
- TdpDraw (GraphInfo[i].drawport);
- }
-
- FOREVER
- {
- /*
- * VOloWinEventPoll: Poll for the next window event.
- * The polling mode used is V_WAIT.
- * Therefore, VOloWinEventPoll does not
- * return until a masked event is
- * generated. V_WAIT always produces
- * a valid location object.
- * VUerHandleLocEvent: Service the event. This routine will check
- * if the event is used by any input objects
- * that may be in the view.
- */
- location = VOloWinEventPoll (V_WAIT);
- event_req_status = VUerHandleLocEvent (location);
- if (event_req_status == INPUT_UNUSED)
- {
-
- /*
- * VOloType: returns the type of event. These types
- * match event types specified in VOscWinEventMask.
- */
- switch (VOloType (location))
- {
-
- case V_RESIZE:
- /*
- * The window size has been changed.
- * TscReset: Resets all screen drawports after window
- * resizing.
- */
- TscReset (screen);
- break;
-
- case V_EXPOSE:
- /*
- * VOloRegion: Returns a rectangle representing the
- * exposed region on the screen.
- * TscRedraw: After erasing, redraws all the drawports
- * in the screen.
- * A portion of the window has been exposed and needs
- * to be redrawn.
- */
- TscRedraw (screen, VOloRegion (location));
- break;
-
- case V_KEYPRESS:
- /*
- * Check key selected.
- * VOloKeySym: Returns the key symbol value of the
- * location object
- *
- * If the key symbol represents the characters 'q'
- * or 'Q' then quit the program.
- */
- switch (VOloKeySym (location))
- {
- case 'q':
- case 'Q':
- Quit = YES;
- break;
- }
- break;
-
- case V_BUTTONPRESS:
- /*
- * Check button selected.
- * VOloButton: Returns the button that was pressed
- * TloGetSelectedDrawport: Gets selected drawport
- * TdpDrawNext: Updates all dynamic objects (arrow)
- *
- * The left mouse button acts as the selection button.
- * Check to see if the user selected a graph drawport.
- * If so, then set the current graph drawport and
- * draw this graph_drawport on the top. The right
- * mouse button exits the program.
- */
- switch (VOloButton (location))
- {
- case 1:
- selected_drawport = TloGetSelectedDrawport (location);
- GetCurrentDrawport (selected_drawport);
- TdpDrawNext (main_drawport);
- break;
-
- case 3:
- Quit = YES;
- break;
-
- default:
- break;
- }
- break;
- }
- }
- if (Quit == YES)
- break;
- }
-
- /*--------------------
- * Termination
- *
- * TdpDestroy: Destroy the drawport,
- * TviCloseData: Close the data sources of the view
- * TviDestroy: Destroy the view, freeing the allocated memory
- * TscClose: Closes the screen object
- * TTerminate: Perform the clean-up for DV-Tools
- */
- TscErase (screen);
- for (i = 0; i < MAX_GRAPHS; i++)
- {
- TdpDestroy (GraphInfo[i].drawport);
- TviCloseData (GraphInfo[i].view);
- TviDestroy (GraphInfo[i].view);
- }
- TdpDestroy (main_drawport);
- TviDestroy (main_view);
- TscClose (screen);
- TTerminate ();
- return (EXIT_OK);
- }
-
-
- /*--------------
- * HandleInput -- Service result routine called when a selection
- * is made from the main menu. Check the selection made and perform
- * the appropriate action.
- */
- /*ARGSUSED*/
- LOCAL int
- HandleInput (client, er, label, loc, args)
- OBJECT client;
- EVENT_REQUEST er;
- int label;
- OBJECT loc;
- ADDRESS args;
- {
- char incrdecrflag;
- double scale;
- int i;
- OBJECT dp_xform;
-
- /*
- * Clear message string
- */
- TdpEraseObject (main_drawport, msg_object);
- VOtxSetString (msg_object, "");
- TdpDrawObject (main_drawport, msg_object);
-
- /*
- * Check the menu selection and perform the appropriate action
- * based on the menu selection.
- */
- switch ((int) (control_var))
- {
- /*
- * Read the next iteration of data from each view and
- * update all dynamic objects with new data.
- */
- case UPDATE:
- for (i = 0; i < MAX_GRAPHS; i++)
- {
- TviReadData (GraphInfo[i].view);
- TdpDrawNext (GraphInfo[i].drawport);
- }
- break;
-
- /*
- * TdpGetScale: Gets scale factor of a drawport
- * TdpZoom: Scales the drawing in the drawport
- * TdpRedraw: Redraws a portion of the drawport
- *
- * Check the current scale of the drawport. Then scale the
- * drawport by the scale factor defined by ZoomInScale.
- */
- case ZOOM_IN:
- if (TdpGetScale (GraphInfo[current_graph].drawport) < 1.0)
- {
- TdpZoom (GraphInfo[current_graph].drawport, ZoomInScale);
- TdpRedraw (GraphInfo[current_graph].drawport,
- ENTIRE_DRAWPORT, YES);
- CurrentScale[current_graph] *= ZoomInScale;
- }
- break;
-
- /*
- * TdpGetScale: Gets scale factor of a drawport
- * TdpZoom: Scales the drawing in the drawport
- * TdpRedraw: Redraws a portion of the drawport
- *
- * Check the current scale of the drawport. Then scale the
- * drawport by the scale factor defined by ZoomOutScale.
- */
- case ZOOM_OUT:
- if (TdpGetScale (GraphInfo[current_graph].drawport) > (1 / 14171.0))
- {
- TdpZoom (GraphInfo[current_graph].drawport, ZoomOutScale);
- dp_xform = TdpGetXform (GraphInfo[current_graph].drawport,
- DR_TO_SCREEN);
- if (VOdgIsDrawable (GraphInfo[current_graph].graph, dp_xform) == YES)
- {
- TdpRedraw (GraphInfo[current_graph].drawport,
- ENTIRE_DRAWPORT, YES);
- CurrentScale[current_graph] *= ZoomOutScale;
- }
- else
- {
- VOtxSetString (msg_object,
- "Graph cannot be displayed properly; Drawport is not scaled");
- TdpDrawObject (main_drawport, msg_object);
- TdpZoom (GraphInfo[current_graph].drawport, ZoomInScale);
- }
- }
- break;
-
- /*
- * Reset the graph drawports to the beginning and return the
- * drawports to their original scale. Then redraw them.
- */
- case RESET:
- for (i = 1; i <= 3; i++)
- VPvd_drange (GraphInfo[current_graph].vdplist[i],
- GraphInfo[current_graph].low_range[i],
- GraphInfo[current_graph].high_range[i]);
- VPdgdfreset (GraphInfo[current_graph].dgp_ptr);
-
- scale = 1.0 / CurrentScale[current_graph];
- TdpZoom (GraphInfo[current_graph].drawport, scale);
- TdpRedraw (GraphInfo[current_graph].drawport, ENTIRE_DRAWPORT, YES);
- CurrentScale[current_graph] *= scale;
- break;
-
- /*
- * Increase the ranges for all variable descriptors associated
- * with the current graph. Then redraw the drawport displaying
- * this graph.
- */
- case INCR_RANGE:
- incrdecrflag = 'i';
- ChangeRange ((ADDRESS) & incrdecrflag);
- TdpRedraw (GraphInfo[current_graph].drawport, ENTIRE_DRAWPORT, YES);
- break;
-
- /*
- * Decrease the ranges for all variable descriptors associated
- * with the current graph. Then redraw the drawport displaying
- * this graph.
- */
- case DECR_RANGE:
- incrdecrflag = 'd';
- ChangeRange ((ADDRESS) & incrdecrflag);
- TdpRedraw (GraphInfo[current_graph].drawport, ENTIRE_DRAWPORT, YES);
- break;
-
- /*
- * Quit the program
- */
- case QUIT:
- Quit = YES;
- break;
- }
-
- return (int) INPUT_USED;
- }
-
- /*-------------
- * GetObjects -- Obtain rectangle objects from the main view
- * which define areas to display graphs. Create
- * drawports for each graph to be displayed.
- */
- void
- GetObjects (screen, drawing)
- OBJECT screen;
- OBJECT drawing;
- {
- OBJECT graph_areas, graph_drawing;
- OBJECT dyn_control_object, vd_object, arrow;
- RECTANGLE vvp_screen, wvp_rect, svp_offset;
- VARDESC vdp;
- ADDRESS *vdplist;
- int numvars, i;
-
- /* TdrGetNamedObject: Gets a named object from a drawing.
- * VOinGetVarList: Gets a variable descriptor list of
- * the input object.
- * TvdPutBuffer: Set a new variable descriptor buffer
- *
- * Obtain the control menu from the main view. Then, rebind
- * it's vdp to a program variable.
- */
- control_menu = TdrGetNamedObject (drawing, "control_menu");
- VOinGetVarList (control_menu, &vdplist, &numvars);
- TvdPutBuffer (vdplist[0], (ADDRESS) & control_var);
-
- /*
- * VUerServiceResultPost: Post a service result request
- * with the event handler.
- *
- * Post a service result request which monitors the
- * menu. The request specifies the type of the service
- * result flag to be generated as an INPUT_DONE. INPUT_DONE
- * indicates an input sequence has been completed
- * (a menu selection was made).
- */
- VUerServiceResultPost ((OBJECT) MENU_CLIENT, (VUERFCNFUNPTR)HandleInput, (ADDRESS)NULL, 0,
- control_menu, (int)INPUT_DONE, (int)0);
-
- /* Load in the views containing the graphs to be displayed in the
- * main drawport. Create a drawport for each graph to be displayed
- * using the rectangles from the main view as the dimensions for
- * these drawports.
- */
- for (i = 0; i < MAX_GRAPHS; i++)
- {
- graph_areas = TdrGetNamedObject (drawing, Graph_Areas[i]);
- VOobBox (graph_areas, &wvp_rect, &svp_offset);
- vvp_screen.ll.x = wvp_rect.ll.x + XMAX;
- vvp_screen.ll.y = wvp_rect.ll.y + YMAX;
- vvp_screen.ur.x = wvp_rect.ur.x + XMAX;
- vvp_screen.ur.y = wvp_rect.ur.y + YMAX;
-
- GraphInfo[i].view = TviLoad (Graph_Areas[i]);
- GraphInfo[i].drawport = TdpCreateStretch (screen, GraphInfo[i].view,
- &vvp_screen, &whole_world);
-
- /*
- * TobForEachSubobject: Traverses all subobjects in an object.
- * VOdrObDelete: Deletes an object from a drawing
- *
- * For each graph object in the graph drawing, obtain the
- * information such as dgp and range of vdp. Delete the
- * graph area rectangle from the main drawing.
- */
- graph_drawing = TviGetDrawing (GraphInfo[i].view);
- TobForEachSubobject (graph_drawing, (TOBFOREACHSUBOBJFUNPTR)GetGraph, (ADDRESS) & i);
- VOdrObDelete (drawing, graph_areas);
- }
-
- /*
- * VOobDyGet: Returns the dynamic control object attached to
- * the object.
- * VOdyGetDataObj: Returns the first data control object attached
- * to the dynamic object.
- * VOvdGetVdp: Gets the pointer to the variable descriptor
- *
- * Obtain the variable descriptor for the arrow which is
- * to be used to indicate which graph is the currently selected
- * graph.
- */
- arrow = TdrGetNamedObject (drawing, "arrow");
- dyn_control_object = VOobDyGet (arrow);
- vd_object = VOdyGetDataObj (dyn_control_object, V_DYN_PATH_MOVE, 1);
- vdp = VOvdGetVdp (vd_object);
- TvdPutBuffer (vdp, (ADDRESS) & arrow_var);
-
- /*
- * VOtxSetString: Redefines string associated with the text object.
- *
- * Obtain the message text object and initialize the string.
- */
- msg_object = TdrGetNamedObject (drawing, "msg_object");
- VOtxSetString (msg_object, "");
- }
-
-
- /*----------
- * GetGraph -- Obtain the graph object, it's data group pointer and
- * the variable descriptors associated with this graph.
- * Also obtain the range of the vdps for the graph.
- */
- ADDRESS
- GetGraph (object, args)
- OBJECT object;
- ADDRESS args;
- {
- int i, num_of_vdps;
- int *graph_index = (int *)args;
-
- /*
- * VOobType: Returns the type flag of an object
- * VOdgGetDgp: Returns pointer to the data group structure
- * VGdgvd: Gets the address or number of vdps from a data group
- */
- if (VOobType (object) == OT_DG)
- {
- GraphInfo[*graph_index].graph = object;
- GraphInfo[*graph_index].dgp_ptr = VOdgGetDgp (object);
- num_of_vdps = (int) VGdgvd (GraphInfo[*graph_index].dgp_ptr, 0);
- for (i = 1; i <= num_of_vdps; i++)
- {
- GraphInfo[*graph_index].vdplist[i] = (VARDESC) VGdgvd (
- GraphInfo[*graph_index].dgp_ptr, i);
- VGvd_drange (GraphInfo[*graph_index].vdplist[i],
- &GraphInfo[*graph_index].low_range[i],
- &GraphInfo[*graph_index].high_range[i]);
- }
- }
-
- return V_CONTINUE_TRAVERSAL;
- }
-
-
- /*--------------------
- * GetCurrentDrawport -- Determine which drawport is the currently
- * selected drawport. The actions selected from the main menu are
- * performed on the currently selected drawport. The currently
- * selected drawport is pointed to by an arrow object which moves
- * along a path based on which drawport is currently selected.
- */
- void
- GetCurrentDrawport (drawport)
- DRAWPORT drawport;
- {
- int i;
-
- /*
- * TdpFront: Moves a drawport to the front
- * TdpRedraw: Redraws a portion of the drawport
- */
- for (i = 0; i < MAX_GRAPHS; i++)
- {
- if (drawport == GraphInfo[i].drawport)
- {
- current_graph = i;
- arrow_var = graph_arrow_val[i];
- TdpFront (GraphInfo[current_graph].drawport);
- TdpRedraw (GraphInfo[current_graph].drawport, ENTIRE_DRAWPORT, YES);
- break;
- }
- }
- }
-
-
- /*-------------
- * ChangeRange -- Called when user selected from main menu
- * to increase or decrease the variable ranges on the graph.
- */
- void
- ChangeRange (incrdecr)
- ADDRESS incrdecr;
- {
- double low, high, newhigh;
- int i, num_of_vdps;
-
- num_of_vdps = 3;
- for (i = 1; i <= num_of_vdps; i++)
- {
- VGvd_drange (GraphInfo[current_graph].vdplist[i], &low, &high);
- if (*incrdecr == 'd')
- {
- newhigh = (high - low) / 2.0;
- if (low >= newhigh)
- newhigh = high;
-
- /* Set a minimum value which cannot be exceeded. */
- if ((newhigh > 0.0) && (newhigh < 0.00000000001))
- newhigh = 0.00000000001;
- else if ((newhigh < 0) && (newhigh < -0.00000000001))
- newhigh = -0.00000000001;
- }
- else
- {
- newhigh = 2.0 * high;
- if ((newhigh > 0.0) && (newhigh > 10000000000.0))
- newhigh = 10000000000.0;
- else if ((newhigh < 0.0) && (newhigh < -10000000000.0))
- newhigh = -10000000000.0;
- }
-
- VPvd_drange (GraphInfo[current_graph].vdplist[i], low, newhigh);
- }
-
- /*
- * VPdgdfreset: Resets the display formatter associated with
- * a data group.
- */
- VPdgdfreset (GraphInfo[current_graph].dgp_ptr);
- }
-